package com.ce.tag;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;

import org.apache.commons.beanutils.PropertyUtils;

import com.ce.framework.util.DateUtil;
import com.ce.framework.util.StringUtil;
import com.ce.framework.util.Uuid;

public class HtmlTableTag extends HtmlBaseTag {
	private static final long serialVersionUID = 1L;
	private String value;
	private int offset;
	private int length;
	private String trattrs;
	public List<Column> cols = new ArrayList<Column>();
	public List<ColSpan> colspans = new ArrayList<ColSpan>();
	public HashMap<String,String> fieldMap = new HashMap<String, String>();
	
	private Iterator<Object> it;//数据循环器
	
	/** 初始化数据 */
	@SuppressWarnings("unchecked")
	protected void initData(){
	    HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
		Object obj = pageContext.getAttribute(value);
		if(obj==null){
			obj = request.getAttribute(value);
		}
		if(obj==null){
			obj = request.getSession().getAttribute(value);
		}
		if(obj instanceof Collection){
			it = ((Collection<Object>)obj).iterator();
		}
		if(it!=null){
			for(int i=0;i<offset;i++){//定位至offset的指定位置
				it.next();
			}
		}
	}

	@Override
	public int doStartTag() throws JspException {
		cols.clear();
		colspans.clear();
		return super.doStartTag();
	}

	public int doEndTag() throws JspException {
		initData();
	    JspWriter out = pageContext.getOut();
		try {
			out.print("<table");
			out.print(getHtmlAttrString());
			out.println(">");
			out.println("<colgroup>");
			for (Column c : cols) {
				out.println(c.getColHtml());
			}
			out.println("</colgroup>");
			out.println("<thead>");
			for (Column c : cols) {
				if("#chk".equals(c.getText())){
					c.setText("<input type=checkbox name=chkAll />");
				}
				out.println(c.getThHtml());
			}
			out.println("</thead>");
			out.println("<tbody>");
			if(it!=null){
				Object o=null;
				int i=0;
				while(it.hasNext()&&(length<=0||i<length)){
					o = it.next();i++;
					out.println("<tr "+getCalcVal(trattrs,o,null)+">");
					for (Column c : cols) {
						out.println(c.getTdHtml(o,i));
					}
					out.println("</tr>");
				}
			}
			out.println("</tbody>");
	    	out.println(getBodyContent().getString().trim());
			out.println("</table>");
			for(ColSpan cs:colspans){
				out.println(new StringBuffer("<script>spanTblCol('").append(cs.from).append("','").append(cs.to).append("','").append(cs.text).append("','").append(cs.attrs.replaceAll("'", "\\'").replaceAll("\n", "\\n").replaceAll("\r", "\\r")).append("');</script>").toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	    transOrderByName();
		return super.doEndTag();
	}
	/**
	 * 将排序字段转换为汉字
	 */
	private void transOrderByName() {
		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
		if(request.getAttribute("orderBy")!=null){
			String orderBy = (String) request.getAttribute("orderBy");
			orderBy = orderBy.trim().toUpperCase();
			LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
			int stack = 0,pos=0,len = orderBy.length();
			for(int i=0;i<=len;i++){//对order by子句进行拆分，为解析to_date(t.vc_no,'yyyy-mm')等方法，对括号进行简单的配对解析
				if(i==len || (orderBy.charAt(i)==',' && stack==0)){
					String tmp = orderBy.substring(pos,i).trim();
					String key = tmp.endsWith("DESC")?tmp.replaceAll("\\s+DESC", ""):tmp.replaceAll("(\\s+ASC)?", "");
					if(!map.containsKey(key)){
						map.put(key, tmp.endsWith("DESC")?"倒序":"正序");
					}
					pos = i+1;
				}
				else if(orderBy.charAt(i)=='('){
					stack++;
				}
				else if(orderBy.charAt(i)==')'){
					stack--;
				}
			}
			StringBuffer buff = new StringBuffer();
			for(String key:map.keySet()){
				String sort = map.get(key);
				if(!fieldMap.containsKey(key)){
					key = key.replaceAll(".*(\\w{1,9}\\.[A-Z_$]+).*", "$1");
				}
				if(!fieldMap.containsKey(key)){
					System.err.println("排序字段"+key+"不能解析--"+request.getRequestURI());
				}
				else{
					buff.append("－").append(fieldMap.get(key)).append("(").append(sort).append(")");
				}
			}
			if(buff.length()>0){
				request.setAttribute("orderByName", "排序规则："+buff.substring(1));
			}
		}
	}
	Pattern pat1 = Pattern.compile("\\#\\{\\s*([^\\}]+)\\s*\\}");
	Pattern isnum = Pattern.compile("[\\#0\\.,]+");
	DecimalFormat df = new DecimalFormat();
	public String getCalcVal(String exp,Object o,String format){
		if(StringUtil.isBlank(exp)){
			return "";
		}
		String val = exp;
		Matcher mat = pat1.matcher(val);
		while(mat.find()){//表中需要显示多个属性合并的内容
			String name = mat.group(1);
			String value = getObjVal(o, name, format);
			val = val.replace("#{"+name+"}", value);
		}
		return val;
	}
	public String getObjVal(Object o,String field,String format){
		if(o==null){
			return "";
		}
		String val=null;
		Object v = null;
		try {
			v = PropertyUtils.getProperty(o,field);
		} catch (Exception e) {
		}
		if(v instanceof Date){
			val = DateUtil.format((Date) v,StringUtil.isBlank(format)?"yyyy-MM-dd":format);
		}
		else if(v instanceof Number){
			df.applyPattern(format!=null&&isnum.matcher(format).matches()?format:"#");
			val = df.format(v);
		}
		else{
			val = v==null?"":v.toString();
		}
		return val;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public int getOffset() {
		return offset;
	}

	public void setOffset(int offset) {
		this.offset = offset;
	}

	public int getLength() {
		return length;
	}

	public void setLength(int length) {
		this.length = length;
	}
	public String getTrattrs() {
		return trattrs;
	}

	public void setTrattrs(String trattrs) {
		this.trattrs = trattrs;
	}
	class Column{

		private String width,text,field,format,attrs,sort;
		
		public Column() {
			super();
		}
		public Column(String width, String text, String field, String format,String sort,
				String attrs, boolean disabled) {
			super();
			this.width = width;
			this.text = text;
			this.field = field;
			this.format = format;
			this.sort = sort;
			this.attrs = attrs==null?"":attrs;
		}
		public String getColHtml(){
			return new StringBuffer("<col width=\"").append(width).append("\"/>").toString();
		}
		public String getThHtml(){
			return new StringBuffer("<th field=\"").append(field).append("\"").append(StringUtil.isNotBlank(sort)?" sort=\""+sort+"\"":"").append(attrs.replaceAll("#\\{.+\\}", "")).append(">").append(text).append("</th>").toString();
		}
		public String getTdHtml(Object o,int index){
			String val = null;
			if(field.indexOf("#")>=0){
				if("#index".equals(field)){
					val = ""+index;
				}
				else if(field.startsWith("#chk")){
					String name = field.length()>5?field.substring(5):"vcId";
					val = "<input type=checkbox name=chkSelf value=\""+getObjVal(o, name, null)+"\" />";
				}
				else{
					val = getCalcVal(field,o,format);
				}
			}
			else{
				val = getObjVal(o, field, format);
			}
			return new StringBuffer("<td").append(getCalcVal(attrs,o,format)).append(">").append(val).append("</td>").toString();
		}
		
		public String getWidth() {
			return width;
		}
		public void setWidth(String width) {
			this.width = width;
		}
		public String getText() {
			return text;
		}
		public void setText(String text) {
			this.text = text;
		}
		public String getField() {
			return field;
		}
		public void setField(String field) {
			this.field = field;
		}
		public String getFormat() {
			return format;
		}
		public void setFormat(String format) {
			this.format = format;
		}
		public String getAttrs() {
			return attrs;
		}
		public void setAttrs(String attrs) {
			this.attrs = attrs;
		}
		public String getSort() {
			return sort;
		}
		public void setSort(String sort) {
			this.sort = sort;
		}

	}
	class ColSpan{

		private String text,from,to,attrs;

		public ColSpan() {
			super();
		}
		public ColSpan(String text, String from, String to,String attrs) {
			super();
			this.text = text;
			this.from = from;
			this.to = to;
			this.attrs = attrs==null?"":attrs;
		}
		public String getHtml(){
			return new StringBuffer("<col width=\"").append(text).append("\"/>").toString();
		}
		public String getText() {
			return text;
		}
		public void setText(String text) {
			this.text = text;
		}
		public String getFrom() {
			return from;
		}
		public void setFrom(String from) {
			this.from = from;
		}
		public String getTo() {
			return to;
		}
		public void setTo(String to) {
			this.to = to;
		}
	}
}
